#icoach module
#!/usr/bin/python
#Filename: icoach.py

import os
import cgi
import logging
import urllib
import rules

from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.api import mail
from google.appengine.ext import db
from google.appengine.ext.webapp import template
from google.appengine.ext.db import djangoforms
from google.appengine.ext.webapp.util import run_wsgi_app


class Profile(db.Model):
     name = db.StringProperty()
     signup_date = db.DateTimeProperty(auto_now_add=True)
     account = db.UserProperty()
     email = db.EmailProperty()
     bday = db.StringProperty()
     phone_car = db.StringProperty(default='AT&T',choices=['AT&T', 'Alltel', 'T-mobile', 'Verizon', 'Virign Mobile',
                                                           'Suncom','Sprint (PCS)', 'Sprint (Nextel)', 'Cingular GoPhone'])
     phone_num = db.PhoneNumberProperty()
     due_date = db.StringProperty()
     pre_weight = db.FloatProperty()
     height = db.IntegerProperty()
     age = db.IntegerProperty()
     bmi = db.FloatProperty()
     tmz = db.StringProperty()
     
class Reminders(db.Model):
    date_added = db.DateTimeProperty(auto_now_add=True)
    date_sent = db.DateTimeProperty()
    profile = db.StringProperty()
    title = db.StringProperty(multiline=True)
    labels = db.StringProperty()
    starts = db.StringProperty()
    ends = db.StringProperty()
    time = db.StringProperty()
    repeats = db.StringProperty()
    privacy = db.StringProperty()
    
class ProfileForm(djangoforms.ModelForm):
    class Meta:
        model = Profile
        exclude = ['account', 'email']

def getCurrentProfile():
    '''Returns the Profile of the current user, or None if the user does not have one or is not logged in.'''
    if users.get_current_user():
        query = Profile.all()
        query.filter('account =',users.get_current_user())
        return query.get()
    logging.debug('No Profile found')
    return None

def getProfile(email):
    '''Returns the Profile of the user with email or None if no one has that email.'''
    query = Profile.all()
    query.filter('email =', email)
    return query.get()

def getReminders(email):
    '''Returns the REminders of the user'''
    query = Reminders.all()
    query.filter('profile =', email)
    return query.get()

def getUser():
    pass

class MainPage(webapp.RequestHandler):
    '''Main Page View'''
    def get(self):
        logging.debug('Begin checking if profile exists for current user')      
        if users.get_current_user() == None: #user is not logged into google.
            logging.debug('No user')
            url = users.create_login_url(self.request.uri)
            url_linktext = 'Login'
            user = ''
        else: #user logged in, check if he has a profile
            logging.debug('User %s logged in' % users.get_current_user().email())
            userProfile = getCurrentProfile()
            if userProfile == None: #no profile, create one
                userProfile = getProfile(users.get_current_user().email()) #try fetching profile via email, in case the admin created it
                if userProfile != None: #user has profile but profile.account is not set, set it.
                    userProfile.account = users.get_current_user()
                    logging.debug('Setting profile.account to this account')
                else:
                    logging.debug('Creating new Profile')
                    email = users.get_current_user().email()
                    userProfile = Profile(account=users.get_current_user(),email=email)
                userProfile.put()
                self.redirect('/profile/%s?action=edit' % email)
            else:
                logging.debug('User already has profile: email=%s' % userProfile.email)
                
            url = users.create_logout_url(self.request.uri)
            url_linktext = 'Logout'
            user = users.get_current_user().email()
        
        if users.is_current_user_admin():
            template_values = {
            'user': user,
            'url': url,
            'url_linktext': url_linktext,
            'admin': True
            }
        else:    
            template_values = {
            'user': user,
            'url': url,
            'url_linktext': url_linktext
            }
        path = os.path.join(os.path.dirname(__file__), 'index.html')
        self.response.out.write(template.render(path, template_values))

class ProfileHandler(webapp.RequestHandler):
    '''Serves up profile for user'''
    def get(self):
        logging.debug('We are in Profile')
        path = self.request.path
        result = path.split('/', 4)
        urlUser = result[2]
        try: url4 = result[3]        
        except: url4 = "None"          
        action = self.request.get('action')       
        logging.debug('urlUser=%s' % urlUser)
        if users.get_current_user():
            useremail = urllib.quote(users.get_current_user().email())
        else:
            useremail = ''
        logging.debug('user=%s' %  useremail)            
        url = users.create_logout_url(self.request.uri)
        url_linktext = 'Logout'
         
        if urlUser == '' and users.is_current_user_admin() : 
            #request for /profile/, show admin all profiles
            logging.debug('admin asking for list of users')
            query = Profile.all()
            userList = [p.email for p in query]
            template_values = {
                               'user' : users.get_current_user(),
                               'url': url,
                               'url_linktext': url_linktext,
                               'userList': userList,
                               'admin': True}
            htmlFile = os.path.join(os.path.dirname(__file__), 'userlist.html')
            self.response.out.write(template.render(htmlFile, template_values))
        
        elif url4 == 'messages' and users.is_current_user_admin(): 
            #request for /profile/{{ user }}/messages, show admin all messages for {{ user }}          
            query = rules.Messages.all()                  
            template_values = {
                               'user' : users.get_current_user(),
                               'url': url,
                               'url_linktext': url_linktext,
                               'query': query,
                               'admin': True}
            htmlFile = os.path.join(os.path.dirname(__file__), 'query.html')
            self.response.out.write(template.render(htmlFile, template_values))
        
        elif url4 == "reminders" and ((useremail == urlUser) or  users.is_current_user_admin()):
            #asked for /profile/{{ user }}/reminders, show user and admin user's messages             
            query = Reminders.all()
            query.filter('profile =', users.get_current_user().email())
                                  
            template_values = {
                               'user' : users.get_current_user(),
                               'url': url,
                               'url_linktext': url_linktext,
                               'query': query}
            htmlFile = os.path.join(os.path.dirname(__file__), 'reminders.html')
            self.response.out.write(template.render(htmlFile, template_values))  
                                  
        elif action == "edit" and ((useremail == urlUser) or  users.is_current_user_admin()):
            email = urllib.unquote(urlUser)
            userProfile = getProfile(email)
            if userProfile == None: #that user does not exist, redirect to home
                self.redirect("/")
            template_values = {
                               'user' : users.get_current_user(),
                               'url': url,
                               'url_linktext': url_linktext,                              
                               'edit': True,
                               'ProfileForm': ProfileForm(instance=userProfile)}                
            htmlFile = os.path.join(os.path.dirname(__file__), 'profile.html')
            self.response.out.write(template.render(htmlFile, template_values))  
                                                 
        elif users.get_current_user() and ((useremail == urlUser) or  users.is_current_user_admin()): 
            #show user or admin user's profile, ONLY (for now)
            email = urllib.unquote(urlUser)
            userProfile = getProfile(email)
            if userProfile == None: #that user does not exist, create an empty profile, but DO NOT PUT() it in database
                userProfile = Profile()          
            template_values = {
                               'user': urllib.unquote(urlUser),
                               'url': url,
                               'url_linktext': url_linktext,
                               'bday': userProfile.bday,
                               'phone_car' : userProfile.phone_car,
                               'phone_num': userProfile.phone_num,
                               'due_date': userProfile.due_date,
                               'pre_weight': userProfile.pre_weight,
                               'height': userProfile.height,
                               'age': userProfile.age,
                               'bmi': userProfile.bmi,
                               'name': userProfile.name,
                               'tmz': userProfile.tmz,
                               'edit': False,
                               }                
            htmlFile = os.path.join(os.path.dirname(__file__), 'profile.html')
            self.response.out.write(template.render(htmlFile, template_values))
            
        else: #no such user, put up error page.
            logging.debug('No such user')
            template_values = {
                               'user': 'Login',
                               'url': '/',
                               'url_linktext': 'Login'
                               }
            path = os.path.join(os.path.dirname(__file__), 'index.html')
            self.response.out.write(template.render(path, template_values))
   
    def post(self):
        """Update the user's profile with the information in the POST"""
        logging.debug('We are posting to Profile')
        path = self.request.path
        #hkeys = self.request.headers.keys()
        #if 'Referer' in hkeys:
        #    referer = self.request.headers['Referer']
                    
        result = path.split('/', 4)
        urlUser = result[2]
        try: url4 = result[3]        
        except: url4 = "None" 
        logging.debug('urlUser=%s' % urlUser)
        useremail = urllib.quote(users.get_current_user().email())
        logging.debug('posting to user=%s' % useremail)
        logging.debug('url4: %s' % url4)
        account = urllib.unquote(urlUser)
        theProfile = getProfile(account)
                
        if url4 == "reminders":            
            #user or admin wants to add reminder
            newReminder = Reminders(profile=account,title=self.request.get('title'),labels=self.request.get('labels'),
                                   starts=self.request.get('starts'),ends=self.request.get('ends'),time=self.request.get('time'),
                                   repeats=self.request.get('repeats'),privacy='private')
            newReminder.put()
            self.get()
            logging.debug('Added reminder for: %s' % urlUser)            
        elif theProfile and ((useremail == urlUser) or  users.is_current_user_admin()):
            #user wants to update profile
            data = ProfileForm(data=self.request.POST, instance=theProfile)
            if data.is_valid():
                logging.info('Data is valid')
                #save the data, and redirect to the view page
                entity = data.save(commit=False)
                entity.account = users.get_current_user()
                entity.email = theProfile.email
                entity.put()
                self.redirect('/profile/%s' % theProfile.email)
            else:
                logging.info('Data is not valid')
                self.redirect('/profile/%s?action=edit' % useremail)
                #reprint the form
                #template_values = {'ProfileForm': ProfileForm(instance=userProfile)}                
                #htmlFile = os.path.join(os.path.dirname(__file__), 'edit.html')
                #self.response.out.write(template.render(htmlFile, template_values))                  
            
                #user or admin wants to update profile
                #theProfile.bday = self.request.get('bday')
                #theProfile.phone_car = self.request.get('phone_car')
                #theProfile.phone_num = self.request.get('phone_num')
                #theProfile.pre_weight = self.request.get('pre_weight')
                #theProfile.due_date = self.request.get('due_date')
                #theProfile.height = self.request.get('height')
                #theProfile.age = self.request.get('age')
                #theProfile.bmi = self.request.get('bmi')
                #theProfile.name = self.request.get('name')
                #theProfile.tmz = self.request.get('timezone')
                #theProfile.put()
                #self.get()
        elif theProfile == None and users.is_current_user_admin(): 
            #the admin is requesting the creation of a new profile
            #NOTE that these profiles have account=None
            theProfile = Profile(email=account,bday=self.request.get('bday'),phone_car=self.request.get('phone_car'),
                                 name=self.request.get('name'),phone_num=self.request.get('phone_num'),
                                 due_date=self.request.get('due_date'),pre_weight=self.request.get('pre_weight'),
                                 age=self.request.get('age'),bmi=self.request.get('bmi'),height=self.request.get('height'),tmz=self.request.get('timezone'))
            theProfile.put()
            self.get()
        else:
            logging.debug('No such user')
            template_values = {
                               'user': 'Login',
                               'url': '/',
                               'url_linktext': 'Login'
                               }
            path = os.path.join(os.path.dirname(__file__), 'index.html')
            self.response.out.write(template.render(path, template_values))            
               
class Admin(webapp.RequestHandler):
    def get(self):    
        if users.is_current_user_admin():
            url = users.create_logout_url(self.request.uri)
            url_linktext = 'Logout'       
            template_values = {
                               'url': url,
                               'url_linktext': url_linktext,
                               'admin': True
                               }                
            htmlFile = os.path.join(os.path.dirname(__file__), 'admin.html')
            self.response.out.write(template.render(htmlFile, template_values))
        else:
            logging.debug('No such user')
            template_values = {
                               'user': 'Login',
                               'url': '/',
                               'url_linktext': 'Login'
                               }
            path = os.path.join(os.path.dirname(__file__), 'index.html')                    
        
application = webapp.WSGIApplication([('/', MainPage), ('/profile/.*', ProfileHandler), ('/admin/', Admin)], debug=True)
  
def main():
     logging.getLogger().setLevel(logging.DEBUG)
     run_wsgi_app(application)

if __name__ == "__main__":
     main()
